#include "stdafx.h"
#include "Model.h"

#include "Item.h"
#include "PropertyTemplate.h"
#include "ItemCategory.h"
#include "Town.h"
#include "Alchemy.h"
#include "Pred.h"

#include <algorithm>

#ifdef WIN32
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#endif

namespace serika
{
	namespace dq
	{
		Model::Model()
			: mUnconfirm(0)
		{
		}

		Model::~Model()
		{
		}

		void Model::Initialize()
		{
		}

		void Model::Finalize()
		{
			if (mUnconfirm)
			{
				delete mUnconfirm;
			}

			this->ClearList(mItems);
			this->ClearList(mNewItems);
			this->ClearList(mTowns);
			this->ClearMap(mPropTmplMap);
			this->ClearMap(mCategoriesMap);
			this->ClearList(mAlchemies);
		}

		template<class List>
		void Model::ClearList(List& l)
		{
			for (List::iterator itr = l.begin();
				itr != l.end(); ++itr)
			{
				delete (*itr);
			}
			l.erase(l.begin(), l.end());
		}

		template<class Map>
		void Model::ClearMap(Map& m)
		{
			for (Map::iterator mapItr = m.begin(); mapItr != m.end(); ++mapItr)
			{
				this->ClearList(mapItr->second);
			}
		}

		// static 
		const Items& Model::GetItems()
		{
			return ModelSngl::Instance()->mItems;
		}

		// static
		void Model::AddItem(Item* item)
		{
			ModelSngl::Instance()->mItems.push_back(item);
			ModelSngl::Instance()->SortItems();
		}

		// static
		void Model::AddItems(const Items& items)
		{
			Items& me = ModelSngl::Instance()->mItems;
			me.insert(me.end(), items.begin(), items.end());
			ModelSngl::Instance()->SortItems();
			ModelSngl::Instance()->SortItems();
		}

		// static
		void Model::AddNewItem(Item* item)
		{
			Items& me = ModelSngl::Instance()->mNewItems;
			me.push_back(item);
			Item*& unconfirm = ModelSngl::Instance()->mUnconfirm;
			ASSERT(unconfirm == item);
			unconfirm = 0;
		}

		// static
		void Model::PullNewItems(Items& items)
		{
			Items& me = ModelSngl::Instance()->mNewItems;
			items = me;
			me.clear();
		}

		// static
		void Model::SetUnconfirm(Item* item)
		{
			Item*& unconfirm = ModelSngl::Instance()->mUnconfirm;
			if (unconfirm)
			{
				delete unconfirm;
			}
			unconfirm = item;
		}

		// static
		const PropertyTemplates& Model::GetPropertyTemplates(int itemType)
		{
			return ModelSngl::Instance()->mPropTmplMap[itemType];
		}

		// static
		void Model::AddPropertyTemplates(int itemType, const PropertyTemplates& tmpls)
		{
			PropertyTemplates& t = ModelSngl::Instance()->mPropTmplMap[itemType];
			t.insert(t.end(), tmpls.begin(), tmpls.end());
		}

		// static
		const ItemCategories& Model::GetItemCategories(int itemType)
		{
			return ModelSngl::Instance()->mCategoriesMap[itemType];
		}

		// static
		void Model::AddItemCategories(int itemType, const ItemCategories& categories)
		{
			ItemCategories& c = ModelSngl::Instance()->mCategoriesMap[itemType];
			c.insert(c.end(), categories.begin(), categories.end());
		}

		// static
		const Towns& Model::GetTowns()
		{
			return ModelSngl::Instance()->mTowns;
		}

		// static
		void Model::AddTowns(const Towns& towns)
		{
			Towns& t = ModelSngl::Instance()->mTowns;
			t.insert(t.end(), towns.begin(), towns.end());
		}

		// static
		const Alchemies& Model::GetAlchemies()
		{
			return ModelSngl::Instance()->mAlchemies;
		}

		// static
		void Model::AddAlchemies(const Alchemies& alchemies)
		{
			Alchemies& a = ModelSngl::Instance()->mAlchemies;
			a.insert(a.end(), alchemies.begin(), alchemies.end());
		}

		void Model::SortItems()
		{
			std::sort(mItems.begin(), mItems.end(), LessItemIdPred());
		}
	}
}
